<?php

namespace App\Common\SDK\Domain;

class FenZhangTong extends Base
{
    /**
     * 子账户类型: 普通资金分户
     */
    const SUB_ACCOUNT_TYPE_ORDINARY_CAPITAL_SPLIT = '01';

    protected $platNo = '';

    public function __construct()
    {
        parent::__construct();

        $this->platNo = env('FEN_ZHANG_TONG_PLATNO');
    }

    private function sign($params)
    {
        $digest = self::arraySort($params);
        $file = file_get_contents(resource_path('fenzhangtong/sdj-key.pem')); // 证书
        $key = openssl_pkey_get_private($file);
        openssl_sign($digest, $signature, $key, OPENSSL_ALGO_SHA256);
        openssl_free_key($key);
        $sign = base64_encode($signature);
        $params['signData'] = $sign;
        foreach ($params as &$value) {
            $value = $this->characet($value, 'UTF-8');
        }

        return $params;
    }

    protected function assembleParams($params)
    {
        $params['platNo'] = $this->platNo;
        if (!isset($params['transId'])) {
            $params['transId'] = substr(app('Barryvdh\Debugbar\LaravelDebugbar')->getRequestIdGenerator()->generate(), 1);
        }
        $params = $this->sign($params);

        return $params;
    }

    protected function requestAfter($response)
    {
        $response = json_decode($response, true);

        if (self::signVerify($response)) {
            if ($response['retCode'] !== '00000') {
                abort(400, '支付渠道发生错误: ' . $response['retMsg']);
            }
            return $response;
        }

        abort(400, '返回数据验签失败');
    }

    /**
     * 个人客户注册申请
     */
    public function individualCustomerRegistrationApplication($params)
    {
        return $this->request(self::METHOD_POST, 'IESI111001', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 创建交易订单
     * @param array $params
     * @return mixed|void
     * @throws \Exception
     */
    public function createTransactionOrder($params = [])
    {
        return $this->request(self::METHOD_POST, 'IESI111007', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 创建支付订单
     */
    public function createPaymentOrder($params = [])
    {
        return $this->request(self::METHOD_POST, 'IESI111008', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 平台提现 (汇总账户向平台一般对公户转账)
     */
    public function platformWithdrawal($params)
    {
        return $this->request(self::METHOD_POST, 'IESI111014', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 平台自有资金分户间转账
     */
    public function transferOfPlatformOwnedFunds($params)
    {
        return $this->request(self::METHOD_POST, 'IESI111015', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 平台分户转会员分户
     */
    public function transferToMemberAccount($params)
    {
        return $this->request(self::METHOD_POST, 'IESI111016', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 分户资金查询
     */
    public function subAccountFundInquiry($params)
    {
        return $this->request(self::METHOD_POST, 'IESI111018', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 微信支付申请
     */
    public function weChatPayApplication($params = [])
    {
        return $this->request(self::METHOD_POST, 'IESI111030', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 查询支付订单状态
     * @param $params
     * @return mixed
     * @throws \Exception
     */
    public function getPaymentOrderDetail($params)
    {
        return $this->request(self::METHOD_POST, 'IESI111038', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    /**
     * 打开收银台申请
     * @param $params
     * @return mixed
     * @throws \Exception
     */
    public function openTheCashierApplication($params)
    {
        return $this->request(self::METHOD_POST, 'IESI111110', $params, Base::FORMATTED_DATA_TYPE_JSON);
    }

    public static function signVerify($a)
    {
        $signData = $a['signData'];
        unset($a['signData']);
        $publickey = file_get_contents(resource_path('fenzhangtong/GuoJiYinHang.cer')); // 证书
        $key = openssl_get_publickey($publickey);
        // 签名原串排序
        $digest = self::arraySort($a);
        $ok = (bool) openssl_verify($digest, base64_decode($signData), $key, "SHA256");
        openssl_free_key($key);
        return $ok;
    }

    /**
     * @param $arr
     * @param $key
     * @return mixed 删除指定元素返回Array
     */
    public function arrayRemove($arr, $key)
    {
        if (!property_exists($arr, $key)) {
            return $arr;
        }
        $arr = $this->objectArray($arr);
        $keys = array_keys($arr);
        $index = array_search($key, $keys);
        if ($index !== FALSE) {
            array_splice($arr, $index, 1);
        }
        return $arr;
    }

    /**
     * PHP stdClass Object转array
     * @param $array
     * @return array
     */
    public function objectArray($array)
    {
        if (is_object($array)) {
            $array = (array) $array;
        }
        if (is_array($array)) {
            foreach ($array as $key => $value) {
                $array[$key] = $this->objectArray($value);
            }
        }

        return $array;
    }

    protected static function arraySort($data)
    {
        // 排序
        ksort($data);
        $str = '';
        foreach ($data as $k => $v) {
            if (is_array($v)) {
                $t = self::array2string($v);
            } else {
                $t = $v;
            }
            $str .= '|' . $t;
        }

        return substr($str, 1);
    }

    /**
     * 二维数组 key=value 数组转原数据字符串
     * @param $array
     * @return string
     */
    protected static function array2string($array)
    {
        $string = '[';
        if ($array && is_array($array)) {
            foreach ($array as $key => $value) {
                if ($value && is_array($value)) {
                    if ($key != 0) {
                        $string .= ', {';
                    } else {
                        $string .= '{';
                    }
                    $string_s = [];
                    foreach ($value as $k => $v) {
                        $string_s[] .= ' ' . $k . '=' . $v;
                    }
                    $stringc = implode(',', $string_s);
                    $stringc = substr($stringc, 1);
                    $string .= $stringc;
                    $string .= '}';
                }
            }
        }
        $string .= ']';

        return $string;
    }

    public function characet($data, $targetCharset)
    {
        if (!empty($data)) {
            $fileType = "UTF-8";
            if ((int) strcasecmp($fileType, $targetCharset) !== 0) {
                $data = mb_convert_encoding($data, $targetCharset, $fileType);
            }
        }

        return $data;
    }
}
